home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Code Resources / Windows 95 MDEF / Sourcery / Windows95 MDEF.cpp < prev   
C/C++ Source or Header  |  1996-06-12  |  21KB  |  654 lines

  1. /*
  2.     Windows95 MDEF Emulator
  3.     Version 2.0
  4.  
  5.     Evolved from the NeXT MDEF
  6.     written on Jan. 17, 1994 (Right after the Northridge earthquake—whew!!)
  7.  
  8.     by Hiep Dam, From The Witches' Brew
  9.     Contact: America Online -> StarLabs
  10.              Internet       -> starlabs@aol.com
  11.  
  12.  
  13.     FREE! FREE! FREE!
  14.     This code & MDEF are in the public domain.
  15.  
  16.  
  17.     Usage:
  18.     
  19.         Default resource id of MDEF: 1972
  20.         Go into ResEdit and edit the menu's MDEF ID to 1972. That's it!
  21.  
  22.         If you just use the MDEF by itself, by default the menus will have
  23.         a nice 3D grayish look. Your average 3D color customized look...
  24.         Nice, but boring to some.
  25.         
  26.         ...
  27.  
  28.         However, things get more exciting if you add custom resources.
  29.         The MDEF looks for any resources of type 'MnuT' ("Menu template")
  30.         that are the same resource id as the menu. If it doesn't find any
  31.         then it looks for one with the default id of 0. Barring that it
  32.         uses the default look mentioned above.
  33.         
  34.         The 'MnuT' resources define how the Windows95 MDEF colors and draws
  35.         the menu. You specify 3 RGB colors: the menu background color, the
  36.         menu hilite (light) color, and the menu shadow (dark) color. The
  37.         shadow color will also be used to hilite the selected menu item for
  38.         that menu. You must also specify in the 'MnuT' resource the menu's
  39.         font, font size, and font face.
  40.         
  41.         The use of 'MnuT' makes the Windows95 MDEF very versatile and gives
  42.         you control over the color scheme and font appearance of your
  43.         menus. Note: 'mctb' resources are not supported; they're
  44.         really too overblown for my tastes.
  45.  
  46.  
  47.     Notes:
  48.  
  49.     What this MDEF supports:
  50.         * Menu items as submenu items (i.e. points to a submenu w/ a triangle)
  51.         * as a submenu itself
  52.         * cmd-keys
  53.         * item marks
  54.         * item text styles
  55.     
  56.     What this MDEF does not support:
  57.         * meta-characters and parsing menu item text for such characters
  58.         * icons, sicns, reduced icons, cicns. In other words, no icons.
  59.         * scrolling. If you have a lot of menu items, the ones near the
  60.           bottom of the screen will be clipped. Don't use too many items!
  61.     
  62.  
  63.  
  64.     1) This MDEF makes several IMPORTANT *assumptions* about the environment
  65.         it's running on. Running in an incorrect environment will result
  66.         in messy crashes.
  67.             a) Color Quickdraw is present. It uses RGBColors to draw the menu,
  68.                 not the old-style 8-color Quickdraw model. There is no check
  69.                 to see if Color Quickdraw is available or not. If the MDEF is
  70.                 running in a b&w environment, there will be an "unimplemented
  71.                 trap" error. The MDEF absolutely requires Color QD.
  72.             b) System 7 is present.
  73.  
  74.     2) The original portions of the NeXT MDEF were derived from an example MDEF
  75.         included in THINK Reference. See "Custom Menus" in the Menu Manager
  76.         section. The code has changed significantly with the move over to
  77.         a Windows95 look from the NeXT look.
  78.     
  79.     3) I think this code is a good place to start when writing your own
  80.         customized MDEFs. Note that to write MDEFs which support more than just
  81.         the most rudimentary stuff (i.e. more than plain text) things can get
  82.         hairy pretty fast. You have to take into account submenus, item
  83.         marks, command keys, large icons, small icons, and so on. And if
  84.         you want to support extensions such as other modifier keys like
  85.         control, shift, and option keys; whew, it's a lot of work. I
  86.         don't envy the author of the Mercutio MDEF...
  87.  
  88.  
  89.     Version History:
  90.     1.0: Initial release (limited to a source code CD-ROM); was NeXT MDEF
  91.  
  92.     2.0: 11/28/95
  93.          Modified mdef -> now Windows95 MDEF. Boxy menu item look removed
  94.          (admittedly it had looked rather tacky).
  95.          Pretty much complete overhaul. Gotta say it: my old code was
  96.          pretty messy...
  97.  
  98.     2.0.1: 12/1/95
  99.         Fixed submenu problem partially by using mbSaveLoc. What a
  100.         pain! I have to muck around low-memory system globals JUST
  101.         TO MAKE THE DARN THING WORK! Most of the stuff can be found
  102.         in the mChooseMsg handler.
  103.         Also "fixed" popup menu problem using a sample MDEF written
  104.         by Ken Worley. Thanks Ken! (The popup menu still might pop
  105.         up incorrectly if the system 7 popup menu cdef is used and
  106.         the menu is placed near the edges of the monitor. I figure
  107.         it's the system's fault - not mine). Stuff can be found in
  108.         the mPopUpMsg handler.
  109.  
  110. */
  111.  
  112. // ---------------------------------------------------------------------------
  113.  
  114. #include "DrawMenuItem.h"
  115. #include "GetDominantDevice.h"
  116.  
  117. // ---------------------------------------------------------------------------
  118.  
  119. /*
  120.     Writing an MDEF which properly uses submenus (among other things)
  121.     requires that we mess with undocumented system globals, a practice
  122.     that will probably blow up in our faces in the future. Set to
  123.     0 when that time comes, recompile, and voila! Problems should then
  124.     be fixed if we have written the MDEF well.
  125. */
  126.  
  127. #define USE_UNDOCUMENTED_STUFF    1
  128.  
  129. // ---------------------------------------------------------------------------
  130.  
  131. // Some prototypes
  132. pascal void main(short msg, MenuHandle whichMenu, Rect *menuRect,
  133.         Point hitPt, short *itemID);
  134.  
  135.  
  136. static void FillInColor(
  137.     RGBColor *theColor,
  138.     unsigned short r,
  139.     unsigned short g,
  140.     unsigned short b);
  141. static void InitMenuData(short menuID, MDEFstuff *data);
  142.  
  143. static short GetMenuItemHeight();
  144. static short GetMenuHeight(short numItems);
  145. static short FindMenuItem(MenuHandle whichMenu, Rect *menuRect, Point hitPt);
  146. static short GetMenuWidth(MenuHandle whichMenu, short numItems, MDEFstuff *mdefData);
  147.  
  148. static void DoSizeMsg(MenuHandle whichMenu, Rect *menuRect, MDEFstuff *mdefData);
  149. static void DoPopUpMsg(
  150.     MenuHandle    whichMenu,
  151.     Rect        *menuRect,
  152.     short        menuItem,
  153.     Point        hitPt,
  154.     MDEFstuff    *mdefData);
  155. static void DoDrawMsg(MenuHandle whichMenu, Rect *menuRect, MDEFstuff *mdefData);
  156. static void DoChooseMsg(
  157.     MenuHandle    whichMenu,
  158.     Rect        *menuRect,
  159.     Point        hitPt,
  160.     short        *itemID,
  161.     MDEFstuff    *mdefData);
  162.  
  163.  
  164. // ----------------------------------------------------------------------
  165.  
  166. /*
  167.     Main.
  168.  
  169.     This is the entrypoint for the MDEF. So what does that mean? Simply
  170.     this is the function that will be called when the MDEF is used.
  171.     It checks what is the current message sent to it, case goes
  172.     thru a switch statement to find the correct handler for the msg.
  173. */
  174.  
  175. pascal void main(short msg, MenuHandle whichMenu, Rect *menuRect, Point hitPt,
  176.                         short *theMenuItem) {
  177.     MDEFstuff menuData;
  178.     GrafPtr curPort;
  179.     short saveFont, saveSize, saveFace, saveMode;
  180.     RGBColor saveFore, saveBack;
  181.     PenState savePen;
  182.     
  183.     // We're implicitly drawing into the Window Manager port, so make
  184.     // sure we save the important settings so we can restore them later on.
  185.     GetPort(&curPort);
  186.     saveFont = curPort->txFont;
  187.     saveSize = curPort->txSize;
  188.     saveFace = curPort->txFace;
  189.     saveMode = curPort->txMode;
  190.     GetForeColor(&saveFore);
  191.     GetBackColor(&saveBack);
  192.     GetPenState(&savePen);
  193.  
  194.     InitMenuData((**whichMenu).menuID, &menuData);
  195.     TextFont(menuData.params.menuFont);
  196.     TextSize(menuData.params.menuSize);
  197.     TextFace(menuData.params.menuFace);
  198.  
  199.     switch (msg) {
  200.         case mDrawMsg: {
  201.             DoDrawMsg(whichMenu, menuRect, &menuData);
  202.         } break;
  203.     
  204.         case mChooseMsg: {
  205.             DoChooseMsg(whichMenu, menuRect, hitPt, theMenuItem, &menuData);
  206.         } break;
  207.     
  208.         case mSizeMsg: {
  209.             DoSizeMsg(whichMenu, menuRect, &menuData);
  210.         } break;
  211.     
  212.         case mPopUpMsg: {
  213.             DoPopUpMsg(whichMenu, menuRect, *theMenuItem, hitPt, &menuData);
  214.         } break;
  215.     }    // END switch
  216.  
  217.     // Polite manners: if we changed the font, restore the system font
  218.     // upon exiting...
  219.     TextFont(saveFont);
  220.     TextSize(saveSize);
  221.     TextFace(saveFace);
  222.     TextMode(saveMode);
  223.     RGBForeColor(&saveFore);
  224.     RGBBackColor(&saveBack);
  225.     SetPenState(&savePen);
  226. } // END main
  227.  
  228. // ----------------------------------------------------------------------
  229.  
  230. /*
  231.     IsItemDisabled.
  232.  
  233.     Finds out whether the given menu item is disabled or not. Note though
  234.     that we also have to check if the *entire* menu is disabled or not, in
  235.     addition to the menu item. We do this by checking bit 0 of the
  236.     enableFlags field in the menuInfo structure of a menu.
  237.     This is done because the menu can be disabled regardless whether
  238.     the menu item is enabled or not - the menu takes precedence over
  239.     the menu items.
  240.     
  241.     With the advent of Copland, this part will be incompatible. Hopefully
  242.     accessors for a menu item's enabled/disabled state will be available.
  243. */
  244.  
  245. Boolean IsItemDisabled(MenuHandle whichMenu, short whichItem) {
  246.     if (whichItem > 31)
  247.         return(false);    // Items > 31 always enabled
  248.     
  249.     Str255 itemText;
  250.     GetItem(whichMenu, whichItem, itemText);
  251.     if (itemText[1] == kDividerChar)
  252.         return(true);    // Divider menu items always disabled.
  253.  
  254.     return(!BitTst(&(**whichMenu).enableFlags, 31 - whichItem) ||
  255.            !BitTst(&(**whichMenu).enableFlags, 31 - 0));
  256. } // END IsItemDisabled
  257.  
  258. // ----------------------------------------------------------------------
  259.  
  260. /*
  261.     GetMenuItemHeight.
  262.  
  263.     Get the height of any single menu item. If you wish to add icons
  264.     to your menu, you'll have to change this to accomodate larger icons.
  265.     This simply calls _GetFontInfo.
  266. */
  267.  
  268. short GetMenuItemHeight() {
  269.     FontInfo theInfo;
  270.     GetFontInfo(&theInfo);
  271.     // Account for padding for both top and bottom (that's why we're *2)
  272.     return(theInfo.ascent + (kHeightPadding + kHeightPadding));
  273. } // END GetMenuItemHeight
  274.  
  275. // ----------------------------------------------------------------------
  276.  
  277. /*
  278.     GetMenuHeight.
  279.  
  280.     Gets the height of a single menu item, and finds the height
  281.     of the whole menu by multiplying a single menu item height
  282.     by the number of menu items.
  283. */
  284.  
  285. short GetMenuHeight(short numItems) {
  286.     return((numItems * GetMenuItemHeight()) + (kRectPadding + kRectPadding));
  287. } // END GetMenuHeight
  288.  
  289. // ----------------------------------------------------------------------
  290.  
  291. /*
  292.     GetMenuWidth.
  293.  
  294.     Gets the width of the entire menu, by finding the width of the
  295.     widest menu item in the menu. Polls each menu item for its width,
  296.     keeping track of the largest width.
  297.  
  298.     Accounts for submenu "triangles" mini-icon and cmd-keys in menu
  299.     item width.
  300. */
  301.  
  302. short GetMenuWidth(MenuHandle whichMenu, short numItems, MDEFstuff *mdefData) {
  303.     Str255 itemText;
  304.     short maxLength = 0;
  305.     short curLength = 0;
  306.     short theChar;
  307.     short cmdWidth;
  308.     short checkWidth;
  309.     Style style;
  310.     Boolean hasCmdKeys = false;
  311.     
  312.     checkWidth = CharWidth(kCheckMarkChar) +
  313.         kItemMarkPadding + kItemMarkPadding;        // 4 = left & right padding
  314.     cmdWidth = CharWidth(kCmdKeyChar);            // "Cmd" key clover character
  315.     cmdWidth += CharWidth(kWidestChar);                // "W" is widest character in the bunch
  316.  
  317.     for (short i = 1; i <= numItems; i++) {
  318.         GetItem(whichMenu, i, itemText);
  319.         GetItemStyle(whichMenu, i, &style);
  320.         if (style)
  321.             TextFace(style);
  322.         else
  323.             TextFace((mdefData->params).menuFace);
  324.         curLength = StringWidth(itemText);
  325.  
  326.         GetItemCmd(whichMenu, i, &theChar);
  327.         if (theChar != 0)
  328.             hasCmdKeys = true;
  329.  
  330.         curLength += checkWidth;
  331.  
  332.         if (curLength > maxLength)
  333.             maxLength = curLength;
  334.     }
  335.  
  336.     // Padding is both to left and right of cmdKey+char itself.
  337.     if (hasCmdKeys)
  338.         maxLength += (cmdWidth + (kCmdKeyPadding + kCmdKeyPadding));
  339.  
  340.     return(maxLength + (kWidthPadding + kWidthPadding));
  341. } // END GetMenuWidth
  342.  
  343. // ----------------------------------------------------------------------
  344.  
  345. /*
  346.     GetMenuItemRect.
  347.     Determine rect of menu item. Pretty obvious.
  348. */
  349.  
  350. void GetMenuItemRect(Rect *menuRect, Rect *itemRect, short whichItem) {
  351.     short oneHeight = GetMenuItemHeight();
  352.  
  353.     //InsetRect(menuRect, kRectPadding, kRectPadding);
  354.     itemRect->left   = menuRect->left;
  355.     itemRect->right  = menuRect->right;
  356.     itemRect->top    = menuRect->top + (oneHeight * (whichItem - 1));
  357.     itemRect->bottom = itemRect->top + oneHeight;
  358.     //InsetRect(menuRect, -kRectPadding, -kRectPadding);
  359. } // END GetMenuItemRect
  360.  
  361. // ---------------------------------------------------------------------------
  362.  
  363. // FindMenuItem.
  364. // Given a point, find if this point is within the rect of any menu
  365. // item. If so, return the item, else 0.
  366.  
  367. short FindMenuItem(MenuHandle whichMenu, Rect *menuRect, Point hitPt) {
  368.     Rect itemRect;
  369.     short itemCount = CountMItems(whichMenu);
  370.     
  371.     if (!PtInRect(hitPt, menuRect))
  372.         return(0);
  373.  
  374.     for (short i = 1; i <= itemCount; i++) {
  375.         GetMenuItemRect(menuRect, &itemRect, i);
  376.         if (PtInRect(hitPt, &itemRect)) {
  377.             return(i);
  378.         }
  379.     }
  380.     return(0);
  381. } // END FindMenuItem
  382.  
  383. // ---------------------------------------------------------------------------
  384. // ---------------------------------------------------------------------------
  385.  
  386. /*
  387.     DoSizeMsg.
  388.     Even more obvious (más o menos). Calls others to do the job.
  389. */
  390.  
  391. void DoSizeMsg(MenuHandle whichMenu, Rect *menuRect, MDEFstuff *mdefData) {
  392.     short itemCount = CountMItems(whichMenu);
  393.  
  394.     (**whichMenu).menuWidth  = GetMenuWidth(whichMenu, itemCount, mdefData);
  395.     (**whichMenu).menuHeight = GetMenuHeight(itemCount);
  396. } // END DoSizeMsg
  397.  
  398. // ----------------------------------------------------------------------
  399.  
  400. enum {
  401.     kPopupMargin = 4
  402. };
  403.  
  404. void DoPopUpMsg(
  405.     MenuHandle    whichMenu,
  406.     Rect        *menuRect,
  407.     short        menuItem,
  408.     Point        hitPt,
  409.     MDEFstuff    *mdefData) {
  410.     /*
  411.         Note how hitPt.h and hitPt.v are matched to top and left.
  412.         Not intuitive! Another quirk in the OS.
  413.     */
  414.     
  415.     short itemCount = CountMItems(whichMenu);
  416.     menuRect->top = hitPt.h - (menuItem * GetMenuItemHeight());
  417.     menuRect->left = hitPt.v;
  418.     // Get the width & height
  419.     DoSizeMsg(whichMenu, menuRect, mdefData);
  420.     menuRect->right = menuRect->left + (**whichMenu).menuWidth;
  421.     menuRect->bottom = menuRect->top + (**whichMenu).menuHeight;
  422.     
  423.     Rect deviceBounds;
  424.     deviceBounds = (**GetDominantDevice(menuRect)).gdRect;
  425.     if (menuRect->bottom > (deviceBounds.bottom-kPopupMargin))
  426.         OffsetRect(menuRect, 0, (deviceBounds.bottom-kPopupMargin) - menuRect->bottom);
  427.     
  428.     if (menuRect->right > (deviceBounds.right-kPopupMargin))
  429.         OffsetRect(menuRect, (deviceBounds.right-kPopupMargin) - menuRect->right, 0);
  430.     
  431.     if (menuRect->top < (deviceBounds.top+kPopupMargin))
  432.         OffsetRect(menuRect, 0, (deviceBounds.top+kPopupMargin) - menuRect->top);
  433.     
  434.     if (menuRect->left < (deviceBounds.left+kPopupMargin))
  435.         OffsetRect(menuRect, (deviceBounds.left+kPopupMargin) - menuRect->left, 0);
  436. } // END DoPopUpMsg
  437.  
  438. // ---------------------------------------------------------------------------
  439.  
  440. /*
  441.     DoDrawMsg.
  442.     Erases the entire menu, and calls each menu item individually to
  443.     draw itself.
  444. */
  445.  
  446. void DoDrawMsg(MenuHandle whichMenu, Rect *menuRect, MDEFstuff *mdefData) {
  447.     short itemCount = CountMItems(whichMenu);
  448.  
  449.     RGBBackColor(&(mdefData->params).menuBkgndColor);
  450.     EraseRect(menuRect);
  451.  
  452.     PenSize(1, 1);
  453.     InsetRect(menuRect, 1, 1);
  454.     RGBForeColor(&(mdefData->params).menuHiliteColor);
  455.     MoveTo(menuRect->left, menuRect->top);
  456.     LineTo(menuRect->right, menuRect->top);
  457.     MoveTo(menuRect->left, menuRect->top);
  458.     LineTo(menuRect->left, menuRect->bottom);
  459.     RGBForeColor(&(mdefData->params).menuShadowColor);
  460.     MoveTo(menuRect->right, menuRect->bottom);
  461.     LineTo(menuRect->right, menuRect->top);
  462.     MoveTo(menuRect->right, menuRect->bottom);
  463.     LineTo(menuRect->left, menuRect->bottom);
  464.  
  465.     for (short i = 1; i <= itemCount; i++) {
  466.         DrawMenuItem(whichMenu, menuRect, i, kMenuUnhilited, mdefData);
  467.     }
  468.     InsetRect(menuRect, -1, -1);
  469. } // END DoDrawMsg
  470.  
  471. // ----------------------------------------------------------------------
  472.  
  473. #pragma mark UNDOCUMENTED DATA!
  474.  
  475. #if USE_UNDOCUMENTED_STUFF
  476. /*
  477.     Define some undocumented low-memory system globals. You can bet
  478.     yer dollar this will break in future releases of the MacOS, but
  479.     doing this is a necessary evil, as it is required to make the
  480.     MDEF work __properly__ with submenus.
  481. */
  482.  
  483. // mbSaveLoc, mbItemRect, and mbUglyScroll stuff
  484. typedef struct {
  485.     short    lastMBSave;
  486.     long    mbCustomStorage;
  487.     Rect    mbItemRect;            // Greatest item of interest to us currently
  488.     char    mbMenuDelay;
  489.     char    mbMenuDrag;
  490.     short    mbUglyScroll;        // Of semi-interest (tho what it does I don't know)
  491.     short    mbIconState;
  492.     long    mbHeader;            // Actually, size is unknown!
  493. } MBGlobalData;
  494.  
  495. #define mbItemRectOffset    6
  496. #define mbUglyScrollOffset    16
  497.  
  498. #define sgMBSaveLoc            *((Handle*)0x0B5C)
  499. #define sgMBItemRectPtr        ((Rect*)((*sgMBSaveLoc) + mbItemRectOffset))
  500. #define sgMBUglyScrollPtr    ((short*)((*sgMBSaveLoc) + mbUglyScrollOffset))
  501. #define sgHuhRectPtr        ((Rect*)0x09FA)
  502.  
  503. // menuDisable stuff
  504. typedef struct {
  505.     short hiWord;
  506.     short loWord;
  507. } StuffedLong;
  508.  
  509. #define sgMenuDisablePtr    ((StuffedLong*)0x0B54)
  510.  
  511. #endif // USE_UNDOCUMENTED_STUFF
  512.  
  513. // ---------------------------------------------------------------------------
  514.  
  515. /*
  516.     DoChooseMsg.
  517.     This is the only other function which calls DrawMenuItem, other than
  518.     DoDrawMsg. Takes care of the hiliting/unhiliting of menu items.
  519. */
  520.  
  521. void DoChooseMsg(
  522.     MenuHandle    whichMenu,
  523.     Rect        *menuRect,
  524.     Point        hitPt,
  525.     short        *itemID,
  526.     MDEFstuff    *mdefData) {
  527.  
  528.     Str255 itemText;
  529.     short mouseItem;
  530.     
  531.     mouseItem = FindMenuItem(whichMenu, menuRect, hitPt);
  532.  
  533.     if (mouseItem != 0) {
  534.         // Pre-fetch some data we'll need later on (item text)
  535.         GetItem(whichMenu, mouseItem, itemText);
  536.  
  537. #if USE_UNDOCUMENTED_STUFF
  538.         /*
  539.             Boo-hoo-hoo! We need to set the mbItemRect stored in mbSaveLoc.
  540.  
  541.             All UNDOCUMENTED, but REQUIRED if you wish to make your mdef
  542.             work properly with submenus. Thank God for Usenet and sample
  543.             source code! If this is taken out, the submenus flash about
  544.             5 times, cause they get the mDrawMsg 5 times for some reason!
  545.             Thus they erase, redraw 5 times, causing significant flicker.
  546.  
  547.             Yuck.
  548.         */
  549.         Rect itemRect;
  550.         GetMenuItemRect(menuRect, &itemRect, mouseItem);
  551.         *sgMBItemRectPtr    = itemRect;
  552.         
  553.         /*
  554.             Either using the below lines or commenting them out doesn't
  555.             seem to make any difference so far. So the less we muck
  556.             with the system the safer we'll be. Uncomment when the
  557.             purpose(s) are found...
  558.         */
  559.         // *sgMBUglyScrollPtr    = true;
  560.         // *sgHuhRectPtr        = itemRect;    // MenuSelect seems to be needing this
  561. #endif // USE_UNDOCUMENTED_STUFF
  562.     }
  563.  
  564.     InsetRect(menuRect, 1, 1);
  565.     if (mouseItem == 0 ||                        // out of bounds or disabled
  566.         IsItemDisabled(whichMenu, mouseItem)) {            
  567.  
  568.         DrawMenuItem(whichMenu, menuRect, *itemID, kMenuUnhilited, mdefData);
  569.         *itemID = 0;                // return "cancel" code
  570.  
  571.     }
  572.     else if (mouseItem != *itemID) {
  573.         // unhilight previous
  574.         DrawMenuItem(whichMenu, menuRect, *itemID, kMenuUnhilited, mdefData);
  575.         // hilight new
  576.         DrawMenuItem(whichMenu, menuRect, mouseItem, kMenuHilited, mdefData);
  577.         // return new
  578.         *itemID = mouseItem;
  579.         
  580.     }
  581.  
  582. #if USE_UNDOCUMENTED_STUFF
  583.     // Set the MenuDisable low-mem global; whether the
  584.     // item is disabled or not doesn't matter.
  585.     sgMenuDisablePtr->hiWord = (**whichMenu).menuID;
  586.     sgMenuDisablePtr->loWord = mouseItem;
  587. #endif // USE_UNDOCUMENTED_STUFF
  588.  
  589.     InsetRect(menuRect, -1, -1);
  590. } // END DoChooseMsg
  591.  
  592. // ----------------------------------------------------------------------
  593.  
  594. void InitMenuData(short menuID, MDEFstuff *data) {
  595.     MDEFstuff **menuParameters;
  596.     
  597.     FillInColor(&data->white, kWhite, kWhite, kWhite);
  598.     FillInColor(&data->black, kBlack, kBlack, kBlack);
  599.     
  600.     // If an optional 'MnuT' resource exists, which describes the
  601.     // menu color and font usage, load that. Else fill in default
  602.     // values for MDEF.
  603.     menuParameters = (MDEFstuff**)GetResource(kDefaultMDEFparametersType,
  604.         menuID);
  605.     if (menuParameters == NULL) {
  606.         // Can't find an 'MnuT' with same id as menu. Try default 'MnuT' rsrc id...
  607.         menuParameters = (MDEFstuff**)GetResource(
  608.             kDefaultMDEFparametersType, kDefaultMDEFparametersID);
  609.     }
  610.  
  611.     if (menuParameters == NULL) {
  612.         (data->params).menuHiliteColor = data->white;
  613.         FillInColor(&(data->params).menuBkgndColor, kLtGray, kLtGray, kLtGray);
  614.         FillInColor(&(data->params).menuShadowColor, kDkGray, kDkGray, kDkGray);
  615.         (data->params).menuSelectionColor = (data->params).menuShadowColor;
  616.         (data->params).menuFont = kMenuFont;
  617.         (data->params).menuSize = kMenuSize;
  618.         (data->params).menuFace = kMenuFace;
  619.         (data->params).exactWin95Look = false;
  620.     }
  621.     else {
  622.         HLock((Handle)menuParameters);
  623.         BlockMove(*menuParameters, &data->params, sizeof(MDEFparameters));
  624.         HUnlock((Handle)menuParameters);
  625.         ReleaseResource((Handle)menuParameters);
  626.     }
  627. } // END InitMenuData
  628.  
  629. // ---------------------------------------------------------------------------
  630.  
  631. /*
  632.     FillInColor.
  633.     If you use RGBColors, no doubt you'll be using some function similar to this.
  634.     Now why didn't Apple include a function like this? Less overhead, I guess.
  635.  
  636.     Apple should also have included get/set routines for a grafport's txFont,
  637.     txSize, txFace, and txMode. But who's perfect?
  638. */
  639.  
  640. void FillInColor(
  641.     RGBColor *theColor,
  642.     unsigned short r,
  643.     unsigned short g,
  644.     unsigned short b) {
  645.  
  646.     theColor->red   = r;
  647.     theColor->green = g;
  648.     theColor->blue  = b;
  649. } // END FillInColor
  650.  
  651. // ---------------------------------------------------------------------------
  652. // ---------------------------------------------------------------------------
  653.  
  654. // END Windows95 MDEF.cpp